package com.jsh.erp.service.WorkflowConfig;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.jsh.erp.constants.BusinessConstants;
import com.jsh.erp.constants.ExceptionConstants;
import com.jsh.erp.datasource.entities.*;
import com.jsh.erp.datasource.mappers.*;
import com.jsh.erp.exception.BusinessRunTimeException;
import com.jsh.erp.exception.JshException;
import com.jsh.erp.service.depotHead.DepotHeadService;
import com.jsh.erp.service.depotItem.DepotItemService;
import com.jsh.erp.service.log.LogService;
import com.jsh.erp.service.systemConfig.SystemConfigService;
import com.jsh.erp.service.user.UserService;
import com.jsh.erp.utils.IdUtils;
import com.jsh.erp.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Service
public class WorkflowConfigService {
    private Logger logger = LoggerFactory.getLogger(WorkflowConfigService.class);

    @Resource
    private WorkflowConfigMainMapper workflowConfigMainMapper;
    @Resource
    private WorkflowConfigMainMapperEx workflowConfigMainMapperEx;
    @Resource
    private WorkflowConfigDetailMapper workflowConfigDetailMapper;
    @Resource
    private WorkflowProcessDetailMapper workflowProcessDetailMapper;
    @Resource
    private WorkflowProcessDetailHisMapper workflowProcessDetailHisMapper;
    @Resource
    private LogService logService;
    @Resource
    private UserService userService;
    @Resource
    private DepotHeadMapper depotHeadMapper;
    @Resource
    private DailyHeadMapper dailyHeadMapper;
    @Resource
    private AccountHeadMapper accountHeadMapper;
    @Resource
    private SystemConfigService systemConfigService;
    @Resource
    private DepotItemService depotItemService;
    @Resource
    private DepotHeadService depotHeadService;


    public WorkflowConfigMain getWorkflowConfigMain(String id) throws Exception {
        return workflowConfigMainMapper.selectByPrimaryKey(id);
    }


    public List<WorkflowConfigMain> select(String flowName, int offset, int rows) throws Exception {
        List<WorkflowConfigMain> list = null;
        try {
            list = workflowConfigMainMapperEx.selectByConditionConfig(flowName, offset, rows);
        } catch (Exception e) {
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }

        return list;
    }

    public Long countWorkflowConfigMain(String flowName) throws Exception {
        Long result = null;
        try {
            result = workflowConfigMainMapperEx.countsFlowConfig(flowName);
        } catch (Exception e) {
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int insertWorkflowConfigMain(JSONObject obj, HttpServletRequest request) throws Exception {
        WorkflowConfigMain workflowConfigMain = JSONObject.parseObject(obj.toJSONString(), WorkflowConfigMain.class);
        workflowConfigMain.setUploadFlag("0");
        int result = 0;
        try {
            result = workflowConfigMainMapper.insertSelective(workflowConfigMain);
            logService.insertLog("流程配置",
                    new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_ADD).append(workflowConfigMain.getFlowName()).toString(), request);
        } catch (Exception e) {
            JshException.writeFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int updateWorkflowConfigMain(JSONObject obj, HttpServletRequest request) throws Exception {
        WorkflowConfigMain workflowDefMain = JSONObject.parseObject(obj.toJSONString(), WorkflowConfigMain.class);
        workflowDefMain.setUploadFlag("0");
        int result = 0;
        try {
            result = workflowConfigMainMapper.updateByPrimaryKeySelective(workflowDefMain);
            logService.insertLog("流程配置",
                    new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(workflowDefMain.getFlowName()).toString(), request);
        } catch (Exception e) {
            JshException.writeFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int deleteWorkflowConfigMain(String id, HttpServletRequest request) throws Exception {
        return batchDeleteWorkflowDefMainByIds(id.toString());
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int batchDeleteWorkflowConfigMain(String ids, HttpServletRequest request) throws Exception {
        return batchDeleteWorkflowDefMainByIds(ids);
    }


    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int batchDeleteWorkflowDefMainByIds(String ids) throws Exception {
        int result = 0;
        List<String> idList = StringUtil.strToStringList(ids);
        //TODO 校检 流程配置表
        List<WorkflowProcessDetail> detailList=null;
        String lanCode = systemConfigService.getLanCode();
        try{
            WorkflowProcessDetailExample example = new WorkflowProcessDetailExample();
            example.createCriteria().andDefineDetailIdIn(idList).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
            detailList=workflowProcessDetailMapper.selectByExample(example);
        }catch(Exception e){
            JshException.readFail(logger, e, lanCode);
        }
        if(detailList!=null&&detailList.size()>0){
            throw new BusinessRunTimeException(ExceptionConstants.DELETE_FORCE_CONFIRM_CODE,
                    "zh".equals(lanCode) ? ExceptionConstants.DELETE_FORCE_CONFIRM_MSG:ExceptionConstants.DELETE_FORCE_CONFIRM_MSG_US);
        }
        //记录日志
        StringBuffer sb = new StringBuffer();
        sb.append(BusinessConstants.LOG_OPERATION_TYPE_DELETE);
        List<WorkflowConfigMain> list = getConfigMainByIds(ids);
        for(WorkflowConfigMain main: list){
            sb.append("[").append(main.getFlowName()).append("]");
        }
        logService.insertLog("流程配置", sb.toString(),StringUtil.getRequest());
        //校验通过执行删除操作
        try{
            result=workflowConfigMainMapperEx.batchDeleteMainByIds(idList);
        }catch(Exception e){
            JshException.writeFail(logger, e, lanCode);
        }
        return result;
    }

    public List<WorkflowConfigMain> getConfigMainByIds(String ids){
        List<String> idList = StringUtil.strToStringList(ids);
        List<WorkflowConfigMain> list = new ArrayList<>();
        try{
            WorkflowConfigMainExample example = new WorkflowConfigMainExample();
            example.createCriteria().andIdIn(idList);
            list = workflowConfigMainMapper.selectByExample(example);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return list;
    }

    public int checkIsNameExist(String id, String name) throws Exception {
        WorkflowConfigMainExample example = new WorkflowConfigMainExample();
        example.createCriteria().andIdNotEqualTo(id).andFlowNameEqualTo(name).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        List<WorkflowConfigMain> list = null;
        try {
            list = workflowConfigMainMapper.selectByExample(example);
        } catch (Exception e) {
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return list == null ? 0 : list.size();
    }

    public void saveConfigUser(WorkflowConfigDetailVo4Body body, HttpServletRequest request) throws Exception {
        WorkflowConfigMain workflowConfigMain = null;
        String lanCode = systemConfigService.getLanCode();
        try {
            List<WorkflowConfigDetail> configDetailVOS = workflowConfigDetailMapper.findByMainIdWithTypeCode(body.getId(),BusinessConstants.FLOW_CONFIG_DTL_APPROVE_TYPE_USER);
            Map<String,String> configDtls = Maps.newHashMap();
            configDetailVOS.stream().forEach(workflowConfigDetailVO -> {
                configDtls.put(workflowConfigDetailVO.getTypeCode()+workflowConfigDetailVO.getTypeValue()+workflowConfigDetailVO.getProcess(),workflowConfigDetailVO.getId());
            });
            //插入新记录
            for (WorkflowConfigDetail detailVO : body.getDetailList()) {
                String busKey = detailVO.getTypeCode()+detailVO.getTypeValue()+detailVO.getProcess();
                //存在的记录则跳过
                if(configDtls.containsKey(detailVO.getTypeCode()+detailVO.getTypeValue()+detailVO.getProcess())) {
                    configDtls.remove(busKey);
                    continue;
                }
                detailVO.setId(IdUtils.getUUID());
                detailVO.setTypeCode(BusinessConstants.FLOW_CONFIG_DTL_APPROVE_TYPE_USER);
                detailVO.setActivityName( "zh".equals(lanCode) ?"审批环节" : "Approval process"+detailVO.getProcess());
                detailVO.setUploadFlag("0");
                workflowConfigDetailMapper.insertSelective(detailVO);
            }
            //删除处理
            for (String configId : configDtls.values()) {
                WorkflowConfigDetail detailVO =new  WorkflowConfigDetail();
                detailVO.setDeleteFlag(BusinessConstants.DELETE_FLAG_DELETED);
                detailVO.setUploadFlag("0");
                WorkflowConfigDetailExample example = new WorkflowConfigDetailExample();
                example.createCriteria().andIdEqualTo(configId);
                workflowConfigDetailMapper.updateByExampleSelective(detailVO,example);
            }
            int size = body.getDetailList().size();
            workflowConfigMain = workflowConfigMainMapper.selectByPrimaryKey(body.getId());
            workflowConfigMain.setStep(size);
            workflowConfigMain.setUploadFlag("0");
            workflowConfigMainMapper.updateByPrimaryKeySelective(workflowConfigMain);
        } catch (Exception e) {
            JshException.writeFail(logger, e, lanCode);
        }
        logService.insertLog("流程配置",
                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(workflowConfigMain.getFlowName()).toString(), request);
    }

    /**
    * @Author: wy
    * @Description: 采购销售单据
    * @DateTime: 2022/7/30 9:31
    * @Params:
    * @Return
    */
    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public void addProcessDetailWithDepot(String id,DepotHead depotHead) throws Exception {
        if ("0".equals(depotHead.getStatus())){
            WorkflowConfigMainExample example = new WorkflowConfigMainExample();
            example.createCriteria().andIdEqualTo(id).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
            List<WorkflowConfigMain> list = null;
            String lanCode = systemConfigService.getLanCode();
            try {
                list = workflowConfigMainMapper.selectByExample(example);
            } catch (Exception e) {
                JshException.readFail(logger, e, systemConfigService.getLanCode());
            }
            if(list!=null&&list.size() > 0) {
                WorkflowConfigMain workflowConfigMain = list.get(0);
                if (null!=workflowConfigMain.getStep()&&workflowConfigMain.getStep()>0){
                    WorkflowConfigDetailExample example1 = new WorkflowConfigDetailExample();
                    example1.createCriteria().andMainIdEqualTo(workflowConfigMain.getId()).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED).andProcessEqualTo(1);
                    List<WorkflowConfigDetail> workflowConfigDetails = workflowConfigDetailMapper.selectByExample(example1);
                    if(workflowConfigDetails!=null&&workflowConfigDetails.size() > 0) {
                        WorkflowConfigDetail detail = workflowConfigDetails.get(0);
                        WorkflowProcessDetail processDetail = new WorkflowProcessDetail();
                        processDetail.setId(IdUtils.getUUID());
                        if ("zh".equals(lanCode)){
                            processDetail.setTaskTitle("新增待审批,编号为"+depotHead.getDefaultNumber());
                        }else {
                            processDetail.setTaskTitle("Added-"+depotHead.getDefaultNumber()+" to be approved");
                        }
                        //任务id
                        processDetail.setDefineDetailId(workflowConfigMain.getId());
                        //单据类型
                        processDetail.setFlowKey(depotHead.getSubType());
                        //第几步
                        processDetail.setProcess(detail.getProcess());
                        //单据id
                        processDetail.setBusinessKey(depotHead.getId());
                        //apiName
                        processDetail.setAttribute2("depotHead");
                        processDetail.setCreateBy(detail.getTypeValue());
                        processDetail.setCreateDate(new Date());
                        processDetail.setAttribute1(detail.getActivityName());
                        processDetail.setSysOwnerCpy(depotHead.getDefaultNumber());
                        processDetail.setUploadFlag("0");
                        workflowProcessDetailMapper.insertSelective(processDetail);

                        }
                }else {
                    depotHead.setStatus(BusinessConstants.BILLS_STATUS_AUDIT);
                    depotHead.setUploadFlag("0");
                    depotHeadMapper.updateByPrimaryKeySelective(depotHead);
                    //更新当前库存
                    depotItemService.updateCurrentStockByHeaderId(depotHead.getId(),true);
                    //修改关联订单状态
                    depotHeadService.changeBillStatus(depotHead.getId());
                    //盘点单状态
                    depotItemService.getTakeStockDepotHead(depotHead.getId());
                }
            }else {
                depotHead.setStatus(BusinessConstants.BILLS_STATUS_AUDIT);
                depotHead.setUploadFlag("0");
                depotHeadMapper.updateByPrimaryKeySelective(depotHead);
                //更新当前库存
                depotItemService.updateCurrentStockByHeaderId(depotHead.getId(),true);
                //修改关联订单状态
                depotHeadService.changeBillStatus(depotHead.getId());
                //盘点单状态
                depotItemService.getTakeStockDepotHead(depotHead.getId());
            }
        }
    }
    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public void addProcessDetailWithDaily(String id,DailyHead dailyHead) throws Exception {
        if ("0".equals(dailyHead.getStatus())){
            WorkflowConfigMainExample example = new WorkflowConfigMainExample();
            example.createCriteria().andIdEqualTo(id).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
            List<WorkflowConfigMain> list = null;
            String lanCode = systemConfigService.getLanCode();
            try {
                list = workflowConfigMainMapper.selectByExample(example);
            } catch (Exception e) {
                JshException.readFail(logger, e, systemConfigService.getLanCode());
            }
            if(list!=null&&list.size() > 0) {
                WorkflowConfigMain workflowConfigMain = list.get(0);
                if (null!=workflowConfigMain.getStep()&&workflowConfigMain.getStep()>0){
                    WorkflowConfigDetailExample example1 = new WorkflowConfigDetailExample();
                    example1.createCriteria().andMainIdEqualTo(workflowConfigMain.getId()).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED).andProcessEqualTo(1);
                    List<WorkflowConfigDetail> workflowConfigDetails = workflowConfigDetailMapper.selectByExample(example1);
                    if(workflowConfigDetails!=null&&workflowConfigDetails.size() > 0) {
                        WorkflowConfigDetail detail = workflowConfigDetails.get(0);
                        WorkflowProcessDetail processDetail = new WorkflowProcessDetail();
                        processDetail.setId(IdUtils.getUUID());
                        if ("zh".equals(lanCode)){
                            processDetail.setTaskTitle("新增待审批,编号为"+dailyHead.getNumber());
                        }else {
                            processDetail.setTaskTitle("Added-"+dailyHead.getNumber()+" to be approved");
                        }
                        //任务id
                        processDetail.setDefineDetailId(workflowConfigMain.getId());
                        //单据类型
                        processDetail.setFlowKey("每日对账");
                        //第几步
                        processDetail.setProcess(detail.getProcess());
                        //单据id
                        processDetail.setBusinessKey(dailyHead.getId());
                        //apiName
                        processDetail.setAttribute2("dailyHead");
                        processDetail.setCreateBy(detail.getTypeValue());
                        processDetail.setCreateDate(new Date());
                        processDetail.setAttribute1(detail.getActivityName());
                        processDetail.setSysOwnerCpy(dailyHead.getNumber());
                        processDetail.setUploadFlag("0");
                        workflowProcessDetailMapper.insertSelective(processDetail);

                    }
                }else {
                    dailyHead.setStatus(BusinessConstants.BILLS_STATUS_AUDIT);
                    dailyHead.setUploadFlag("0");
                    dailyHeadMapper.updateByPrimaryKeySelective(dailyHead);
                }
            }else {
                dailyHead.setStatus(BusinessConstants.BILLS_STATUS_AUDIT);
                dailyHead.setUploadFlag("0");
                dailyHeadMapper.updateByPrimaryKeySelective(dailyHead);
            }
        }
    }
    /**
    * @Author: wy
    * @Description: 财务单据
    * @DateTime: 2022/7/30 9:39
    * @Params:
    * @Return
    */
    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public void addProcessDetailWithAccount(String id,AccountHead accountHead) throws Exception {
        if ("0".equals(accountHead.getStatus())){
            WorkflowConfigMainExample example = new WorkflowConfigMainExample();
            example.createCriteria().andIdEqualTo(id).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
            List<WorkflowConfigMain> list = null;
            String lanCode = systemConfigService.getLanCode();
            try {
                list = workflowConfigMainMapper.selectByExample(example);
            } catch (Exception e) {
                JshException.readFail(logger, e, systemConfigService.getLanCode());
            }
            if(list!=null&&list.size() > 0) {
                WorkflowConfigMain workflowConfigMain = list.get(0);
                if (null!=workflowConfigMain.getStep()&&workflowConfigMain.getStep()>0){
                    WorkflowConfigDetailExample example1 = new WorkflowConfigDetailExample();
                    example1.createCriteria().andMainIdEqualTo(workflowConfigMain.getId()).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED).andProcessEqualTo(1);
                    List<WorkflowConfigDetail> workflowConfigDetails = workflowConfigDetailMapper.selectByExample(example1);
                    if(workflowConfigDetails!=null&&workflowConfigDetails.size() > 0) {
                        WorkflowConfigDetail detail = workflowConfigDetails.get(0);
                        WorkflowProcessDetail processDetail = new WorkflowProcessDetail();
                        processDetail.setId(IdUtils.getUUID());
                        if ("zh".equals(lanCode)){
                            processDetail.setTaskTitle("新增待审批,编号为"+accountHead.getBillNo());
                        }else {
                            processDetail.setTaskTitle("Added-"+accountHead.getBillNo()+" to be approved");
                        }

                        //任务id
                        processDetail.setDefineDetailId(workflowConfigMain.getId());
                        //单据类型
                        processDetail.setFlowKey(accountHead.getType());
                        //第几步
                        processDetail.setProcess(detail.getProcess());
                        //单据id
                        processDetail.setBusinessKey(accountHead.getId());
                        //apiName
                        processDetail.setAttribute2("accountHead");

                        processDetail.setCreateBy(detail.getTypeValue());
                        processDetail.setCreateDate(new Date());
                        processDetail.setAttribute1(detail.getActivityName());
                        processDetail.setSysOwnerCpy(accountHead.getBillNo());
                        processDetail.setUploadFlag("0");
                        workflowProcessDetailMapper.insertSelective(processDetail);

                        logService.insertLog("审批任务",
                                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_AUDIT).append(accountHead.getType()).toString(),
                                StringUtil.getRequest());

                    }
                }
            }else {
                accountHead.setStatus(BusinessConstants.BILLS_STATUS_AUDIT);
                accountHead.setUploadFlag("0");
                accountHeadMapper.updateByPrimaryKeySelective(accountHead);
            }
        }else {
            accountHead.setStatus(BusinessConstants.BILLS_STATUS_AUDIT);
            accountHead.setUploadFlag("0");
            accountHeadMapper.updateByPrimaryKeySelective(accountHead);
        }
    }
}
